using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
using SkinnedModel;

namespace MageDefender.Graphics
{
    /// <summary>
    /// This class uses the SkinnedModel example to display animations in game.
    /// </summary>
    public class DBAnimatedModel : Microsoft.Xna.Framework.DrawableGameComponent
    {
        int id;

        SpriteBatch spriteBatch;

        Model m_Model;
        AnimationPlayer animationPlayer;

        public AnimationPlayer AnimationPlayer
        {
            get { return animationPlayer; }
            set { animationPlayer = value; }
        }

        bool animIdlePlaying = false;
        bool animWalkPlaying = true;

        Effect effect;
        Matrix renderMatrix, worldMatrix, viewMatrix, projMatrix;
        Vector4 vecEye;
        Matrix[] bones;

        SkinningData skinningData = null;

        public SkinningData SkinningData1
        {
            get { return skinningData; }
            set { skinningData = value; }
        }
        AnimationClip clip = null;

        public AnimationClip Clip
        {
            get { return clip; }
            set { clip = value; }
        }

        public SkinningData SkinningData
        {
            get { return skinningData; }
            set { skinningData = value; }
        }

        Texture2D texColor, texNormal, texIcon;

        Vector3 ambientLightColor;
        Vector3 diffuseLightColor;
        Vector3 specularLightColor;
        float specularPower;

        string name = "";
        string nameTexNormal = "";
        string nameTexColor = "";
        string nameIcon;
        string nameShader = "Shaders\\Shader";
        string techniqueShader = "NormalMapping";

        bool initialized = false;
        float rotZ = 0.0f;
        float rotY = 0.0f;
        float rotX = 0.0f;
        float transZ = 0.0f;
        float transY = 0.0f;
        float transX = 0.0f;

        public float RotX
        {
            get { return rotX; }
            set { rotX = value; }
        }

        public float RotY
        {
            get { return rotY; }
            set { rotY = value; }
        }

        public float RotZ
        {
            get { return rotZ; }
            set { rotZ = value; }
        }

        public float TransX
        {
            get { return transX; }
            set { transX = value; }
        }

        public float TransY
        {
            get { return transY; }
            set { transY = value; }
        }

        public float TransZ
        {
            get { return transZ; }
            set { transZ = value; }
        }

        public bool Initialized
        {
            get { return initialized; }
            set { initialized = value; }
        }

        #region Properties
        public Texture2D TexIcon
        {
            get { return texIcon; }
            set { texIcon = value; }
        }

        public string NameIcon
        {
            get { return nameIcon; }
            set { nameIcon = value; }
        }

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public float SpecularPower
        {
            get { return specularPower; }
            set { specularPower = value; }
        }

        public Vector3 AmbientLightColor
        {
            get { return ambientLightColor; }
            set { ambientLightColor = value; }
        }

        public Vector3 DiffuseLightColor
        {
            get { return diffuseLightColor; }
            set { diffuseLightColor = value; }
        }

        public Vector3 SpecularLightColor
        {
            get { return specularLightColor; }
            set { specularLightColor = value; }
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public string TextureNormal
        {
            get
            {
                return nameTexNormal;
            }
            set
            {
                nameTexNormal = value;
            }
        }

        public string TextureColor
        {
            get
            {
                return nameTexColor;
            }
            set
            {
                nameTexColor = value;
            }
        }

        public string ShaderName
        {
            get
            {
                return nameShader;
            }
            set
            {
                nameShader = value;
            }
        }

        public string ShaderTechnique
        {
            get
            {
                return techniqueShader;
            }
            set
            {
                techniqueShader = value;
            }
        }
        #endregion


        public DBAnimatedModel(Game game)
            : base(game)
        {
            m_Model = null;
            AmbientLightColor = new Vector3(0.5f, 0.5f, 0.5f);
            DiffuseLightColor = new Vector3(0.8f, 0.8f, 0.8f);
            SpecularLightColor = new Vector3(0.0f, 0.0f, 0.0f);
            SpecularPower = 32.0f;

            Id = -1;

            nameIcon = "";

            // TODO: Construct any child components here
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            int width = Game.GraphicsDevice.Viewport.Width;
            int height = Game.GraphicsDevice.Viewport.Height;

            worldMatrix = Matrix.Identity;

            initialized = true;

            base.Initialize();
        }

        public void Initialize(Matrix proj, Matrix view)
        {
            projMatrix = proj;
            viewMatrix = view;

            this.Initialize();
        }

        protected override void LoadContent()
        {
            texColor = Game.Content.Load<Texture2D>(nameTexColor);
            texNormal = Game.Content.Load<Texture2D>(nameTexNormal);

            effect = Game.Content.Load<Effect>("SkinnedModel");

            spriteBatch = new SpriteBatch(GraphicsDevice);

            m_Model = Game.Content.Load<Model>(name);

            // Look up our custom skinning information.
            skinningData = m_Model.Tag as SkinningData;

            if (skinningData == null)
                throw new InvalidOperationException
                    ("This model does not contain a SkinningData tag.");

            // Create an animation player, and start decoding an animation clip.
            animationPlayer = new AnimationPlayer(skinningData);

            clip = skinningData.AnimationClips["Start"];

            animationPlayer.StartClip(clip);


            if (nameIcon.Length > 0)
            {
                texIcon = Game.Content.Load<Texture2D>(nameIcon);
            }

            base.LoadContent();
        }

        //public void PlayAnimations(int id)
        //{
        //    switch (id)
        //    {
        //        case 0:
        //            {
        //                if (!animWalkPlaying)
        //                {
        //                    animIdlePlaying = false;
        //                    animWalkPlaying = true;

        //                    clip = skinningData.AnimationClips["Anim_walk"];
        //                    animationPlayer.StartClip(clip);
        //                }
        //                break;
        //            }
        //        case 1:
        //            {

        //                if(!animIdlePlaying)
        //                {
        //                    animIdlePlaying = true;
        //                    animWalkPlaying = false;
        //                    clip = skinningData.AnimationClips["Anim_Idle1"];
        //                    animationPlayer.StartClip(clip);
        //                }
        //                break;
        //            }
        //    }
        //}


        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here

            base.Update(gameTime);
        }

        public void Update(Vector4 eye, Matrix view, Matrix render, GameTime gameTime, TimeSpan timeSpan)
        {
            viewMatrix = view;
            renderMatrix = render;
            vecEye = eye;

            animationPlayer.Update(timeSpan, true, renderMatrix);

            this.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            Matrix[] bones = animationPlayer.GetSkinTransforms();

            // Render the skinned mesh.
            foreach (ModelMesh mesh in m_Model.Meshes)
            {
                foreach (Effect effect in mesh.Effects)
                {
                    effect.Parameters["Bones"].SetValue(bones);
                    effect.Parameters["View"].SetValue(viewMatrix);
                    effect.Parameters["Projection"].SetValue(projMatrix);
                }
                mesh.Draw(SaveStateMode.SaveState);
            }


            base.Draw(gameTime);
        }
    }
}